package com.rtc.call.core

import android.content.Context
import android.media.AudioAttributes
import android.media.AudioManager
import android.media.MediaPlayer
import android.net.Uri
import android.util.Log
import androidx.core.net.toUri
import io.agora.rtc2.ChannelMediaOptions
import io.agora.rtc2.Constants
import io.agora.rtc2.RtcEngine

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import java.io.File

/**
 * Manages RTC channel operations and call states
 * Handles the "进入RTC Channel" steps and call types in the flow diagram
 */
class CallManager(
    private val context: Context,
    private var rtcEngine: RtcEngine?,
    private val configManager: ConfigManager
) {
    private val TAG = "CallManager"
    
    private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
    private var isInChannel = false
    private var currentChannelName: String? = null
    private var greetingPlayer: MediaPlayer? = null
    private var endingPlayer: MediaPlayer? = null

    fun updateRtcEngine(engine: RtcEngine) {
        rtcEngine = engine
    }
    /**
     * Update settings based on configuration changes
     */
    fun updateFromConfig(configType: String) {
        // Update audio settings
        val audioEnabled = configManager.isAudioEnabled(configType)
        val videoEnabled = configManager.isVideoEnabled(configType)
        val speakerEnabled = configManager.isSpeakerEnabled(configType)
        val volumeLevel = configManager.getVolumeLevel(configType)
        val colorfulMode = configManager.isColorfulModeEnabled(configType)
        
        // Apply settings
        enableLocalAudio(audioEnabled)
        enableLocalVideo(videoEnabled)
        setSpeakerEnabled(speakerEnabled)
        setVolume(volumeLevel)
        
        // Apply colorful mode if enabled
        if (colorfulMode) {
            RtcEngineManager.configureForColorfulCall(rtcEngine)
        } else {
            RtcEngineManager.configureForVideoCall(rtcEngine)
        }
        
        Log.d(TAG, "Updated settings from config: $configType")
    }
    
    /**
     * Join an RTC channel
     * This is for "进入RTC Channel" steps in the flow diagram
     */
    fun joinChannel(channelName: String, uid: Int, token: String? = null) {
        if (rtcEngine == null) {
            Log.e(TAG, "RTC Engine is not initialized")
            return
        }
        
        try {
            // Configure channel media options
            val options = ChannelMediaOptions().apply {
                publishCameraTrack = true
                publishMicrophoneTrack = true
                autoSubscribeAudio = true
                autoSubscribeVideo = true
                clientRoleType = Constants.CLIENT_ROLE_BROADCASTER
            }
            
            // Join the channel
           val resultJoin = rtcEngine?.joinChannel(token, channelName, uid, options)
            
            currentChannelName = channelName
            isInChannel = true
            
            Log.d(TAG, "Joining channel: $channelName, uid: $uid , resultJoin : $resultJoin")
        } catch (e: Exception) {
            Log.e(TAG, "Error joining channel: $channelName", e)
        }
    }
    
    /**
     * Leave the current RTC channel
     */
    fun leaveChannel() {
        if (rtcEngine == null || !isInChannel) {
            return
        }
        
        try {
            rtcEngine?.leaveChannel()
            isInChannel = false
            currentChannelName = null
            
            Log.d(TAG, "Left channel")
        } catch (e: Exception) {
            Log.e(TAG, "Error leaving channel", e)
        }
    }
    
    /**
     * Start default call (both audio and video)
     * This is for "默认角色对话" (Default Role Call) in the flow diagram
     */
    fun startDefaultCall() {
        if (rtcEngine == null) {
            Log.e(TAG, "RTC Engine is not initialized")
            return
        }
        
        try {
            // Configure RTC for default call
            RtcEngineManager.configureForAudioCall(rtcEngine)
            
            // Turn on lights if configured
            if (configManager.isLightEnabled(ConfigManager.CONFIG_TYPE_TURNON)) {
                turnOnLights()
            }
            
            Log.d(TAG, "Started default call")
        } catch (e: Exception) {
            Log.e(TAG, "Error starting default call", e)
        }
    }
    
    /**
     * Start colorful call with special effects
     * This is for "对应角色对话" (Role-matched Call) in the flow diagram
     */
    fun startColorfulCall() {
        if (rtcEngine == null) {
            Log.e(TAG, "RTC Engine is not initialized")
            return
        }
        
        try {
            // Configure RTC for colorful call
            RtcEngineManager.configureForColorfulCall(rtcEngine)
            
            // Turn on lights if configured
            if (configManager.isLightEnabled(ConfigManager.CONFIG_TYPE_NFCON)) {
                turnOnLights()
            }
            
            Log.d(TAG, "Started colorful call")
        } catch (e: Exception) {
            Log.e(TAG, "Error starting colorful call", e)
        }
    }
    
    /**
     * Enable/disable local audio
     */
    fun enableLocalAudio(enabled: Boolean) {
        rtcEngine?.enableLocalAudio(enabled)
        Log.d(TAG, "Local audio ${if (enabled) "enabled" else "disabled"}")
    }
    
    /**
     * Enable/disable local video
     */
    fun enableLocalVideo(enabled: Boolean) {
        rtcEngine?.enableLocalVideo(enabled)
        Log.d(TAG, "Local video ${if (enabled) "enabled" else "disabled"}")
    }
    
    /**
     * Mute/unmute local audio
     */
    fun muteLocalAudio(muted: Boolean) {
        rtcEngine?.muteLocalAudioStream(muted)
        Log.d(TAG, "Local audio ${if (muted) "muted" else "unmuted"}")
    }
    
    /**
     * Switch between speaker and earpiece
     */
    fun setSpeakerEnabled(enabled: Boolean) {
        rtcEngine?.setEnableSpeakerphone(enabled)
        Log.d(TAG, "Speaker ${if (enabled) "enabled" else "disabled"}")
    }
    
    /**
     * Set the default audio route to speakerphone
     * @param speakerOn Whether to use speakerphone (true) or earpiece (false) as the default audio route
     */
    fun setDefaultAudioRouteToSpeakerphone(speakerOn: Boolean) {
        rtcEngine?.setDefaultAudioRoutetoSpeakerphone(speakerOn)

        Log.d(TAG, "Default audio route set to ${if (speakerOn) "speakerphone" else "earpiece"}")
    }


    fun playNetWorkSound(url:String, onCompletion: () -> Unit = {}) {

        val uri = url.toUri()
        try {
            greetingPlayer?.stop()
            greetingPlayer?.release()
            greetingPlayer = MediaPlayer().apply {
                setAudioAttributes(
                    AudioAttributes.Builder()
                        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                        .setUsage(AudioAttributes.USAGE_MEDIA)
                        .build()
                )
                setDataSource(context, uri)
                prepare()
                start()
                setOnCompletionListener(){ mp -> onCompletion() }
            }
            Log.d(TAG, "Playing greeting sound: $url")
        }catch (e: Exception) {
            Log.e(TAG, "Error playing greeting sound", e)
        }

    }

    /**
     * Play greeting sound
     * This is for "播放特定声音 流水灯" (Play Special Sound and flowing lights) in the flow diagram
     */
    fun playGreetingSound() {
        coroutineScope.launch(Dispatchers.IO) {
            try {
                val greetingSoundFile = configManager.getGreetingSoundFile(ConfigManager.CONFIG_TYPE_NFCON)
                
                if (greetingSoundFile != null) {
                    val soundFile = File(context.filesDir, greetingSoundFile)
                    
                    if (soundFile.exists()) {
                        greetingPlayer?.release()
                        greetingPlayer = MediaPlayer().apply {
                            setAudioAttributes(
                                AudioAttributes.Builder()
                                    .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                                    .setUsage(AudioAttributes.USAGE_MEDIA)
                                    .build()
                            )
                            setDataSource(context, Uri.fromFile(soundFile))
                            prepare()
                            start()
                        }
                        Log.d(TAG, "Playing greeting sound: $greetingSoundFile")
                    } else {
                        Log.e(TAG, "Greeting sound file does not exist: $greetingSoundFile")
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "Error playing greeting sound", e)
            }
        }
    }
    
    /**
     * Play ending sound
     * This is for "播放特定声音 灯光关闭" (Play Special Sound and lights off) in the flow diagram
     */
    fun playEndingSound() {
        coroutineScope.launch(Dispatchers.IO) {
            try {
                val endingSoundFile = configManager.getEndingSoundFile(ConfigManager.CONFIG_TYPE_NFCOFF)
                
                if (endingSoundFile != null) {
                    val soundFile = File(context.filesDir, endingSoundFile)
                    
                    if (soundFile.exists()) {
                        endingPlayer?.release()
                        endingPlayer = MediaPlayer().apply {
                            setAudioAttributes(
                                AudioAttributes.Builder()
                                    .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                                    .setUsage(AudioAttributes.USAGE_MEDIA)
                                    .build()
                            )
                            setDataSource(context, Uri.fromFile(soundFile))
                            prepare()
                            start()
                        }
                        Log.d(TAG, "Playing ending sound: $endingSoundFile")
                    } else {
                        Log.e(TAG, "Ending sound file does not exist: $endingSoundFile")
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "Error playing ending sound", e)
            }
        }
    }
    
    /**
     * Turn on lights (simulated)
     * This is part of "播放特定声音 流水灯" step in the flow diagram
     */
    fun turnOnLights() {
        // In a real implementation, this would interface with device lights or LED control
        Log.d(TAG, "Turning on lights")
    }
    
    /**
     * Turn off lights (simulated)
     * This is part of "播放特定声音 灯光关闭" step in the flow diagram
     */
    fun turnOffLights() {
        // In a real implementation, this would interface with device lights or LED control
        Log.d(TAG, "Turning off lights")
    }
    
    /**
     * Set audio volume
     * This is for "控制调节音量" (Volume Control) in the flow diagram
     */
    fun setVolume(volume: Int) {
        val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
        val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
        
        // Convert percent (0-100) to device volume range
        val scaledVolume = (volume * maxVolume) / 100
        
        audioManager.setStreamVolume(
            AudioManager.STREAM_MUSIC,
            scaledVolume,
            0
        )
        
        Log.d(TAG, "Set volume to $volume% (device level: $scaledVolume/$maxVolume)")
    }
    
    /**
     * Clean up resources
     */
    fun cleanup() {
        greetingPlayer?.release()
        greetingPlayer = null
        
        endingPlayer?.release()
        endingPlayer = null
    }
} 